package com.hitemole.controller;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.hitemole.input.InputHandler;
import com.hitemole.levelObject.Moles;
import com.hitemole.levelObject.Moles.MOLE_STATE;
import com.hitemole.manager.GameManager;
import com.hitemole.manager.GameManager.GAME_STATES;
import com.hitemole.manager.GameManager.MULTIPLAYER_STATES;
import com.hitemole.network.ClientGame;
import com.hitemole.network.Network.GameMessage;

public class GameClientController {
	private GameManager world;
	private int multiplier;
	private float comboBarIndex;
	private int combo = 3;
	private int index = 1;
	private float time = 5;
	private GAME_STATES tempStates = GAME_STATES.GAME_RESUME;
	Color fontColor;

	public GameClientController(GameManager world) {
		// TODO Auto-generated constructor stub
		this.world = world;
		this.multiplier = 1;
		fontColor = new Color(world.getDefaultBigFont().getColor());
		world.setMultiplayerState(MULTIPLAYER_STATES.BADGUY);
	}

	public void update(float delta) {
		// TODO Auto-generated method stub
		if (Gdx.input.getInputProcessor() == null) {
			Gdx.input.setInputProcessor(InputHandler.InputHandler);
		}
		switch (world.getMultiplayerState()) {
		case BADGUY:
			doBadGuy(delta);
			break;
		case END:
			// go to multiplayer score screen by submitting both score
			break;
		case GOODGUY:
			 doGoodGuy(delta);
			break;
		default:
			break;

		}
	}

	public void doBadGuy(float delta) {
		switch (world.getGameState()) {
		case GAME_END:

			fontColor.a += 0.5f * delta;
			if (fontColor.a >= 1) {
				fontColor.a = 0;
				break;
			}
			world.getDefaultBigFont().setColor(fontColor);
			for (Moles mole : world.getMoles()) {
				mole.stateTime = 0;
				mole.setAnimationKey("empty");
			}
			time -= delta;
			if (time <= 0) {
				time = 5;
				world.setGameState(GAME_STATES.GAME_EXIT);
			}
			break;
		case GAME_EXIT:
			world.setGameState(GAME_STATES.GAME_RESET);
			world.setMultiplayerState(MULTIPLAYER_STATES.GOODGUY);
			// TODO must save this score
			break;
		case GAME_RESUME:
			world.setGameState(tempStates);
			Gdx.input.setInputProcessor(null);
			break;
		case GAME_PAUSE:
			Gdx.input.setInputProcessor(world.getStageUI());
			break;
		case GAME_PROGRESS:
			world.getScores().update(delta);
			world.getHammer().update(delta);
			if (world.getHammer().getCurrentAnimation()
					.isAnimationFinished(world.getHammer().stateTime)) {
				world.getHammer().setDrawAnimation(false);
			}
			for (Moles mole : world.getMoles()) {
				mole.update(delta);
				switch (mole.getState()) {
				case EMPTY:

					break;
				case SHOW:
					mole.setTimeUntilHide(mole.getTimeUntilHide() - delta);
					if (mole.getTimeUntilHide() <= 0) {
						hideMole(mole);
					}
					break;
				default:
					break;

				}
			}
			if (world.getLives() == 0) {
				world.setGameState(GAME_STATES.GAME_END);
			}
			break;
		case GAME_START:
			fontColor.a -= 1.3f * delta;
			if (index < 0 && fontColor.a <= 0) {
				world.setGameState(GAME_STATES.GAME_PROGRESS);
				fontColor.a = 1;
				index = 1;
				world.countDown = GameManager.COUNTDOWN_STRING[2];
				break;
			}
			if (fontColor.a <= 0) {
				world.countDown = GameManager.COUNTDOWN_STRING[index--];
				fontColor.a = 1;
			}
			world.getDefaultBigFont().setColor(fontColor);
			break;
		case GAME_RESET:
			for (Moles mole : world.getMoles()) {
				mole.reset();
			}
			index = 1;
			combo = 3;
			multiplier = 1;
			comboBarIndex = 0;
			world.resetLives();
			world.getComboBar().setEnd((int) comboBarIndex, 100);
			world.getScores().resetScore();
			world.setGameState(GAME_STATES.GAME_START);
			break;
		default:
			break;
		}

		for (int i = 0; i < InputHandler.InputHandler.getUserInput().size(); i++) {
			Vector2 vect = InputHandler.InputHandler.getUserInput().get(i);
			sendMessage(2, (int) vect.x, (int) vect.y);
			InputHandler.InputHandler.getUserInput().remove(i);
		}
		for (int i = 0; i < ClientGame.clientGame.getUserInput().size(); i++) {
			GameMessage gameMessage = ClientGame.clientGame.getUserInput().get(
					i);
			if (gameMessage.id == 1) {
				showHammer((int) gameMessage.mouseClick.x,
						(int) gameMessage.mouseClick.y);
			} else if(gameMessage.id==2){
				showMole((int) gameMessage.mouseClick.x,
						(int) gameMessage.mouseClick.y);
			} else if(gameMessage.id==3){
				hitMole((int) gameMessage.mouseClick.x,
						(int) gameMessage.mouseClick.y);
			}else{
				missMole();
			}
			
			ClientGame.clientGame.getUserInput().remove(i);
		}
	}

	public void doGoodGuy(float delta) {
		switch (world.getGameState()) {
		case GAME_END:
			fontColor.a += 0.5f * delta;
			if (fontColor.a >= 1) {
				fontColor.a = 0;
				break;
			}
			world.getDefaultBigFont().setColor(fontColor);
			for (Moles mole : world.getMoles()) {
				mole.stateTime = 0;
				mole.setAnimationKey("empty");
			}
			break;
		case GAME_EXIT:
			world.goScoreScreen();
			break;
		case GAME_RESUME:
			world.setGameState(tempStates);
			Gdx.input.setInputProcessor(null);
			break;
		case GAME_PAUSE:
			Gdx.input.setInputProcessor(world.getStageUI());
			break;
		case GAME_PROGRESS:
			world.getScores().update(delta);
			world.getHammer().update(delta);
			if (world.getHammer().getCurrentAnimation()
					.isAnimationFinished(world.getHammer().stateTime)) {
				world.getHammer().setDrawAnimation(false);
			}
			for (Moles mole : world.getMoles()) {
				mole.update(delta);
				switch (mole.getState()) {
				case EMPTY:
					break;
				case SHOW:
					mole.setTimeUntilHide(mole.getTimeUntilHide() - delta);
					if (mole.getTimeUntilHide() <= 0) {
						hideMole(mole);
					}
					break;
				default:
					break;

				}
			}
			if (world.getLives() == 0) {
				world.setGameState(GAME_STATES.GAME_END);
			}
			break;
		case GAME_START:
			fontColor.a -= 1.3f * delta;
			if (index < 0 && fontColor.a <= 0) {
				world.setGameState(GAME_STATES.GAME_PROGRESS);
				fontColor.a = 1;
				index = 1;
				world.countDown = GameManager.COUNTDOWN_STRING[2];
				break;
			}
			if (fontColor.a <= 0) {
				world.countDown = GameManager.COUNTDOWN_STRING[index--];
				fontColor.a = 1;
			}
			world.getDefaultBigFont().setColor(fontColor);
			break;
		case GAME_RESET:
			for (Moles mole : world.getMoles()) {
				mole.reset();
			}
			index = 1;
			combo = 3;
			multiplier = 1;
			comboBarIndex = 0;
			world.resetLives();
			world.getComboBar().setEnd((int) comboBarIndex, 100);
			world.getScores().resetScore();
			world.setGameState(GAME_STATES.GAME_START);
			break;
		default:
			break;
		}

		for (int i = 0; i < InputHandler.InputHandler.getUserInput().size(); i++) {
			Vector2 vect = InputHandler.InputHandler.getUserInput().get(i);
			sendMessage(1,(int) vect.x, (int) vect.y);
			InputHandler.InputHandler.getUserInput().remove(i);
		}
		for (int i = 0; i < ClientGame.clientGame.getUserInput().size(); i++) {
			GameMessage gameMessage = ClientGame.clientGame.getUserInput().get(
					i);
			if (gameMessage.id == 1) {
				showHammer((int) gameMessage.mouseClick.x,
						(int) gameMessage.mouseClick.y);
			} else if(gameMessage.id==2){
				showMole((int) gameMessage.mouseClick.x,
						(int) gameMessage.mouseClick.y);
			} else if(gameMessage.id==3){
				hitMole((int) gameMessage.mouseClick.x,
						(int) gameMessage.mouseClick.y);
			}else{
				missMole();
			}
			ClientGame.clientGame.getUserInput().remove(i);
		}
	}
	
	public void hitMole(int screenX, int screenY){
		for (Moles mole : world.getMoles()) {
			// System.out.println(mole.getRelativeCollisionShape().x+" "+screenX);
			if (!mole.getRelativeCollisionShape().contains(screenX, screenY)) {
				continue;
			}
			if (mole.isInteractable()) {
				hideMole(mole);
			}
		}
		combo--;
		if (combo < 0 && combo <= 8) {
			multiplier += 1;
			combo = multiplier * 3;
		}
		world.getScores().addScore(10);
		world.getScores().setMultiplier(multiplier);
		comboBarIndex = (float) ((multiplier * 3) - combo)
				/ (multiplier * 3) * 100;
		world.getComboBar().setEnd((int) comboBarIndex, 100);
	}
	
	public void missMole(){
		combo = 3;
		world.getScores().setMultiplier(1);
		multiplier = 1;
		comboBarIndex = 0;
		world.getComboBar().setEnd((int) comboBarIndex, 100);
		world.decreaseLives();
	}

	private void showMole(int x, int y) {
		// TODO Auto-generated method stub
		for (Moles mole : world.getMoles()) {
			// System.out.println(mole.getRelativeCollisionShape().x+" "+screenX);
			if (!mole.getRelativeCollisionShape().contains(x, y)) {
				continue;
			}
			if (!mole.isInteractable()) {
				showMole(mole);
			}
		}
	}

	public void showRandomMole() {
		int randomMole = MathUtils.random(world.getMoles().size() - 1);
		showMole(world.getMoles().get(randomMole));
	}

	private void showMole(Moles mole) {
		mole.setInteraction(true);
		mole.setState(MOLE_STATE.SHOW);
		mole.stateTime = 0;
		mole.setAnimationKey("full");
		mole.setTimeUntilHide(mole.getCurrentAnimation().animationDuration
				+ (0.5f + (1 / multiplier)));
		mole.getCurrentAnimation().setPlayMode(Animation.NORMAL);
	}

	private void hideMole(Moles mole) {
		mole.setInteraction(false);
		mole.setTimeUntilShow(5 - (multiplier) + MathUtils.random(12));
		mole.stateTime = 0;
		mole.setState(MOLE_STATE.EMPTY);
		mole.getCurrentAnimation().setPlayMode(Animation.REVERSED);
	}

	public void sendMessage(int id,int screenX, int screenY) {
		GameMessage gm = new GameMessage();
		gm.id = id;
		gm.mouseClick = new Vector2(screenX, screenY);
		ClientGame.clientGame.sendToServer(gm);
	}

	public void pause() {
		// TODO Auto-generated method stub
		if (!world.getGameState().equals(GAME_STATES.GAME_PAUSE))
			tempStates = world.getGameState();
		world.setGameState(GAME_STATES.GAME_PAUSE);
	}

	public void showHammer(int screenX, int screenY) {
		world.getHammer().setRelativePosition(
				new Vector2(screenX - (35 * world.getHammer().xScale), screenY
						- (115 * world.getHammer().yScale)));
		world.getHammer().setDrawAnimation(true);
		world.getHammer().stateTime = 0;
	}
}
